<template>
  <a-form :form="form"
          class="form-login-with-phone"
          @submit="handleSubmitForm"
  >
    <a-form-item>
      <a-input placeholder="手机" size="large" v-decorator="formRules.phone" />
    </a-form-item>
    <a-form-item>
      <a-input-search placeholder="手机验证码"
                      size="large"
                      v-decorator="formRules.phone_verification_code"
                      @search="handleSendPhoneVerificationCode"
      >
        <a-button slot="enterButton"
                  :style="{width: '160px'}"
                  :disabled='is_countdown_running || !this.form.getFieldsValue().phone'
        >{{ is_countdown_running ? `${countdown_count}s` : '发送验证码' }}
        </a-button>
      </a-input-search>
    </a-form-item>
    <a-form-item>
      <a-row :gutter="8">
        <a-col :span="14">
          <a-input placeholder="图片验证码" size="large" v-decorator="formRules.captcha_code" />
        </a-col>
        <a-col :span="10">
          <div class='captcha-image-container'>
            <img class='captcha-image'
                 :src='captcha_image_url'
                 title='点击刷新'
                 @click='refreshCaptchaImageUrl'
            >
          </div>
        </a-col>
      </a-row>
    </a-form-item>
    <a-form-item>
      <a-button type="primary"
                size='large' block
                html-type="submit"
                :disabled='is_form_submitting'
                :loading='is_form_submitting'
      >登录
      </a-button>
    </a-form-item>
  </a-form>
</template>

<script>
  import { switchMapTo, tap, timer } from 'rxjs'
  import { takeWhile } from 'rxjs/operators'
  import formRules from '@/form-rules'
  import constants from '@/constants'
  import utils from '@/utils'
  import { mapActions } from 'vuex'

  export default {
    name: 'PhoneLoginForm',
    data () {
      return {
        formRules,

        is_countdown_running: false,
        countdown_count: 60,

        is_loading_captcha_image: true,
        captcha_image_url: '',

        is_form_submitting: false,
      }
    },
    beforeCreate () {
      this.form = this.$form.createForm(this, { name: constants.phone_login_form })
    },
    mounted () {
      this.refreshCaptchaImageUrl()
    },
    methods: {
      ...mapActions([
        'setApiToken',
        'setUser'
      ]),

      // 请求发送验证码
      handleSendPhoneVerificationCode () {
        if (this.is_countdown_running) {
          return
        }

        const fieldsValue = this.form.getFieldsValue()
        this.is_countdown_running = true
        const MAX_COUNT_IN_SECONDS = 60

        const payload = { phone: fieldsValue.phone }
        this.$apiService.sendPhoneVerificationCode(payload).pipe(
          switchMapTo(timer(0, 1000)),
          takeWhile(count => count < MAX_COUNT_IN_SECONDS),
          tap((count) => {
            this.countdown_count = MAX_COUNT_IN_SECONDS - count
          }),
        ).subscribe(
          (res) => {
            console.log('res', res)
          },
          (err) => {
            console.log('err', err)
            this.is_countdown_running = false
          },
          () => {
            this.is_countdown_running = false
          },
        )
      },

      // 刷新 captcha 图片
      refreshCaptchaImageUrl () {
        this.captcha_image_url = utils.generateCaptchaUrl()
      },

      // 验证并提交登录表单
      handleSubmitForm (e) {
        e.preventDefault()
        console.log('handleSubmitForm')

        this.is_form_submitting = true

        // 验证一下数据
        this.form.validateFieldsAndScroll((err, values) => {
          if (err) {
            console.log('Received values of form: ', values)
            this.is_form_submitting = false
            return
          }

          // 登录
          const fieldsValue = this.form.getFieldsValue()
          const payload = {
            phone: fieldsValue.phone,
            phone_verification_code: fieldsValue.phone_verification_code,
            captcha_code: fieldsValue.captcha_code,
          }
          this.$apiService.postLogin(payload).subscribe(
            (res) => {
              console.log('res', res)
              this.is_form_submitting = false
              this.$message.success('登录成功')

              // 保存 token 与用户信息
              const api_token = res.data.api_token
              this.setApiToken({api_token})

              const user = res.data.user
              this.setUser({user})

              this.$emit(constants.form_submitted_successful)
            },
            (err) => {
              console.log('err', err)
              this.is_form_submitting = false
              this.$message.error(err.message)
            },
          )
        })
      },
    },
  }
</script>

<style scoped lang="scss">
  .captcha-image-container {
    width: 150px;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;

    .captcha-image {
      width: 100%;
      height: auto;
      line-height: 40px;
      transform: translateY(-1px);
      cursor: pointer;
    }
  }
</style>
